"""
任务服务模块
提供任务管理的核心业务逻辑
"""

import asyncio
import traceback
from datetime import datetime
from typing import Optional, List, Dict, Any

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, text, desc

from db.models.scan import ScanTask, ScanResult, AIAnalysisResult, ScanRecord
from services.scanner.scanner import Scanner
from core.utils.file_utils import generate_temp_dir, ensure_temp_dir_exists, check_dir_age, remove_expired_dir


class TaskService:
    """任务服务类"""
    
    def __init__(self, db: AsyncSession):
        self.db = db
    
    async def get_task_details(self, task_id: int, request: Dict[str, Any]) -> Dict[str, Any]:
        """
        获取任务详情
        
        Args:
            task_id: 任务ID
            request: 请求参数
            
        Returns:
            包含任务详情的响应字典
        """
        try:
            # 获取任务信息
            task = await self.db.get(ScanTask, task_id)
            if not task:
                raise ValueError("任务不存在")
            
            # 构建基础查询
            base_query = select(ScanResult).where(ScanResult.task_id == task_id)
            
            # 添加筛选条件
            if request.get('file_path'):
                base_query = base_query.where(ScanResult.file_path.like(f"%{request['file_path']}%"))
            
            if request.get('function_name'):
                base_query = base_query.where(ScanResult.function_name.like(f"%{request['function_name']}%"))
            
            if request.get('issue_type'):
                base_query = base_query.where(ScanResult.issue_type == request['issue_type'])
            
            if request.get('severity'):
                base_query = base_query.where(ScanResult.severity == request['severity'])
            
            # 获取总数
            count_query = select(func.count()).select_from(base_query.subquery())
            total_result = await self.db.execute(count_query)
            total = total_result.scalar()
            
            # 添加排序和分页
            page = request.get('page', 1)
            page_size = request.get('page_size', 10)
            query = base_query.order_by(desc(ScanResult.created_at))
            query = query.offset((page - 1) * page_size).limit(page_size)
            
            # 执行查询
            result = await self.db.execute(query)
            results = result.scalars().all()
            
            # 转换为响应格式
            items = []
            for scan_result in results:
                # 构建代码片段（这里可以根据需要从文件中读取实际代码）
                code_snippet = f"// {scan_result.file_path}:{scan_result.start_line}-{scan_result.end_line}"
                
                item = {
                    "id": scan_result.id,
                    "file_path": scan_result.file_path,
                    "function_name": scan_result.function_name,
                    "line_number": f"{scan_result.start_line}-{scan_result.end_line}",
                    "start_line": scan_result.start_line,
                    "end_line": scan_result.end_line,
                    "issue_type": scan_result.issue_type,
                    "severity": scan_result.severity,
                    "message": scan_result.message,
                    "code_snippet": code_snippet,
                    "created_at": scan_result.created_at
                }
                items.append(item)
            
            return {
                "total": total,
                "page": page,
                "page_size": page_size,
                "items": items
            }
            
        except Exception as e:
            print(f"获取任务详情时发生错误: {str(e)}")
            raise
    
    async def get_task_status(self, task_id: int) -> Dict[str, Any]:
        """
        获取任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            包含任务状态的响应字典
        """
        try:
            # 获取任务信息
            task = await self.db.get(ScanTask, task_id)
            if not task:
                raise ValueError("任务不存在")
            
            # 获取问题总数
            issue_count_query = select(func.count(ScanResult.id)).where(ScanResult.task_id == task_id)
            issue_count_result = await self.db.execute(issue_count_query)
            total_issues = issue_count_result.scalar() or 0
            
            # 按严重程度统计问题
            severity_stats_query = select(
                ScanResult.severity,
                func.count(ScanResult.id).label('count')
            ).where(ScanResult.task_id == task_id).group_by(ScanResult.severity)
            
            severity_stats_result = await self.db.execute(severity_stats_query)
            severity_stats = {}
            for row in severity_stats_result:
                severity_stats[row.severity] = row.count
            
            return {
                "id": task.id,
                "status": task.status,
                "total_issues": total_issues,
                "severity_stats": severity_stats,
                "created_at": task.created_at,
                "updated_at": task.updated_at
            }
            
        except Exception as e:
            print(f"获取任务状态时发生错误: {str(e)}")
            raise
    
    async def delete_task(self, task_id: int) -> Dict[str, Any]:
        """
        删除任务
        
        Args:
            task_id: 任务ID
            
        Returns:
            删除结果
        """
        try:
            # 获取任务信息
            task = await self.db.get(ScanTask, task_id)
            if not task:
                raise ValueError("任务不存在")
            
            # 删除相关的扫描结果
            await self.db.execute(
                text("DELETE FROM scan_results WHERE task_id = :task_id"),
                {"task_id": task_id}
            )
            
            # 删除相关的AI分析结果
            await self.db.execute(
                text("DELETE FROM ai_analysis_results WHERE task_id = :task_id"),
                {"task_id": task_id}
            )
            
            # 删除相关的扫描记录
            await self.db.execute(
                text("DELETE FROM scan_records WHERE scan_id = :task_id"),
                {"task_id": task_id}
            )
            
            # 删除任务
            await self.db.execute(
                text("DELETE FROM scan_tasks WHERE id = :task_id"),
                {"task_id": task_id}
            )
            
            await self.db.commit()
            
            return {
                "message": "任务删除成功",
                "task_id": task_id
            }
            
        except Exception as e:
            print(f"删除任务时发生错误: {str(e)}")
            raise
    
    async def retry_task(self, task_id: int) -> Dict[str, Any]:
        """
        重试任务
        
        Args:
            task_id: 任务ID
            
        Returns:
            重试结果
        """
        try:
            # 获取任务信息
            task = await self.db.get(ScanTask, task_id)
            if not task:
                raise ValueError("任务不存在")
            
            # 检查任务状态
            if task.status == "running":
                raise ValueError("任务正在运行中，无法重试")
            
            # 重置任务状态
            await self.db.execute(
                text("""
                    UPDATE scan_tasks 
                    SET status = 'pending', updated_at = :updated_at 
                    WHERE id = :task_id
                """),
                {
                    "task_id": task_id,
                    "updated_at": datetime.now()
                }
            )
            
            # 删除旧的扫描结果
            await self.db.execute(
                text("DELETE FROM scan_results WHERE task_id = :task_id"),
                {"task_id": task_id}
            )
            
            await self.db.commit()
            
            return {
                "message": "任务重试已启动",
                "task_id": task_id,
                "status": "pending"
            }
            
        except Exception as e:
            print(f"重试任务时发生错误: {str(e)}")
            raise 